if SERVER then
	AddCSLuaFile("shared.lua")
end

if CLIENT then
	SWEP.DrawCrosshair = false
	SWEP.ViewModelFOV = 70
	SWEP.ViewModelFlip = true
	SWEP.CSMuzzleFlashes = true
end

SWEP.Base = "weapon_base"

SWEP.Category          		= "ZE"
SWEP.Spawnable          	= false
SWEP.AdminSpawnable     	= false

SWEP.Weight 				= 5
SWEP.AutoSwitchTo       	= false
SWEP.AutoSwitchFrom     	= false

SWEP.Primary.Sound      	= Sound( "Weapon_Pistol.Empty" )
SWEP.Primary.Recoil     	= 1.5
SWEP.Primary.Damage    		= 1
SWEP.Primary.NumShots		= 1
SWEP.Primary.MaxCone       	= 0.03
SWEP.Primary.Cone       	= 0.02
SWEP.Primary.MinCone       	= 0.002
SWEP.Primary.Delay      	= 0.15
SWEP.Knockback				= 400

SWEP.Primary.ClipSize   	= -1
SWEP.Primary.DefaultClip	= -1
SWEP.Primary.Automatic 		= false
SWEP.Primary.Ammo   		= "none"
SWEP.Primary.ClipMax    	= -1

SWEP.Secondary.ClipSize 	= 1
SWEP.Secondary.DefaultClip 	= 1
SWEP.Secondary.Automatic 	= false
SWEP.Secondary.Ammo         = "none"
SWEP.Secondary.ClipMax      = -1

SWEP.PrimaryAnim = ACT_VM_PRIMARYATTACK
SWEP.ReloadAnim = ACT_VM_RELOAD

AccessorFunc(SWEP, "sights", "Sights")
AccessorFunc(SWEP, "knockback", "Knockback")
AccessorFunc(SWEP, "shoot", "LastShootTime")
AccessorFunc(SWEP, "jump", "JumpTime")
AccessorFunc(SWEP, "move", "MoveTime")

if CLIENT then
	function SWEP:DrawHUD()
		local client = LocalPlayer()
		
		local is = self:GetSights()
		
		local x = ScrW()/2
		local y = ScrH()/2
		
		local size = math.max(0.2, self.Primary.Cone * 10)
		
		local cooldown = Lerp(CurTime() - self:GetLastShootTime(), 2, 1)
		local jumpaffect = Lerp(CurTime() - self:GetJumpTime(), 2, 1)
		local moveaffect = Lerp(CurTime() - self:GetMoveTime(), 2, 1)

		size = size * cooldown * jumpaffect

		surface.SetDrawColor(200, 200, 200, 255)
		
		local gap = 20 * size * (is and 0.8 or 1)
		local length = gap + 20 * size
		surface.DrawLine(x - length, y, x - gap, y)
		surface.DrawLine(x + length, y, x + gap, y)
		surface.DrawLine(x, y - length, x, y - gap)
		surface.DrawLine(x, y + length, x, y + gap)
	end
end

function SWEP:SetZoom(state)
    if SERVER then
		local owner = self.Owner
		if state then
			owner:SetFOV(70, 0.2)
		else
			owner:SetFOV(0, 0.2)
		end
    end
end

function SWEP:Initialize()
	self:SetKnockback(self.Knockback)

	self.Primary.RecCone = 0
	self.ConeAffect = 1

	if CLIENT and self.Weapon:Clip1() == -1 then
		self.Weapon:SetClip1(self.Primary.DefaultClip)
	end
	
	self:SetZoom(false)
	self:SetSights(false)
	
	self:SetLastShootTime(CurTime())
	self:SetJumpTime(CurTime())
	self:SetMoveTime(CurTime())

	self:SetDeploySpeed(self.DeploySpeed)

	if self.SetWeaponHoldType then
		self:SetWeaponHoldType(self.HoldType or "pistol")
	end
end

function SWEP:PrimaryAttack()
	local owner = self.Owner
	local wep = self.Weapon

	local cooldown = math.Clamp(CurTime() - self:GetLastShootTime(), 0, 1)
	
	self.Primary.RecCone = Lerp(cooldown, self.Primary.MaxCone, self.Primary.MinCone)
	
	wep:SetNextPrimaryFire(CurTime() + self.Primary.Delay)
	wep:SetNextSecondaryFire(CurTime() + self.Primary.Delay)
	
	if not self:CanPrimaryAttack() then return end
	
	self:EmitSound(self.Primary.Sound, self:GetPos(), 100)
	
	self:ShootBullet(self.Primary.Damage, self.Primary.Recoil, self.Primary.NumShots, self:GetPrimaryCone())
	self:TakePrimaryAmmo(1)
	
	local punch = Lerp(cooldown, 0.5, 0.2)
	owner:ViewPunch(Angle((math.Rand(-(punch - 0.1), -(punch + 0.1)) * self.Primary.Recoil) * self.ConeAffect, (math.Rand(-punch, punch) * self.Primary.Recoil) * self.ConeAffect, 0))
		
	self:SetLastShootTime(CurTime())
end

function SWEP:ShootBullet(dmg, rec, num, cone)
	num = num or 1
	cone = cone or 0.01
	
	local owner = self.Owner
	
	owner:MuzzleFlash()
	
	local bullet 	= {}
	bullet.Num 		= num
	bullet.Src 		= owner:GetShootPos()
	bullet.Dir 		= (owner:EyeAngles() + self.Owner:GetPunchAngle()):Forward()
	bullet.Spread 	= Vector(cone, cone, 0)
	bullet.Tracer	= 4
	bullet.Force	= 100
	bullet.Damage 	= dmg
	
	owner:FireBullets(bullet)
	self:SendWeaponAnim(ACT_VM_PRIMARYATTACK)
	self.Owner:GetViewModel():SetPlaybackRate(1.5)
	owner:SetAnimation(PLAYER_ATTACK1)	
	
	if ((SinglePlayer() and SERVER) or ((not SinglePlayer()) and CLIENT and IsFirstTimePredicted())) then
		rec = self:GetSights() and (rec * 0.6) or rec

		local eyeang = self.Owner:EyeAngles()
		eyeang.pitch = eyeang.pitch - rec * self.ConeAffect
		self.Owner:SetEyeAngles(eyeang)
	end
end

function SWEP:GetPrimaryCone()
	local cone = (self.Primary.RecCone or 0.2) * self.ConeAffect
	return self:GetSights() and (cone * 0.4) or cone
end

function SWEP:DrawWeaponSelection() end

function SWEP:SecondaryAttack()
    if not self.IronSightsPos then return end
    if self.Weapon:GetNextSecondaryFire() > CurTime() then return end
	self.Weapon:SetNextPrimaryFire(CurTime() + 0.3)
	self.Weapon:SetNextSecondaryFire(CurTime() + 0.5)
end

function SWEP:Deploy()
	self:SetLastShootTime(CurTime())
	
	if SERVER then
		self:SetZoom(false)
		self:SetSights(false)
	end
	
	self.Weapon:SendWeaponAnim(ACT_VM_DRAW)
	self.Weapon:SetNextPrimaryFire(CurTime() + self.Weapon:SequenceDuration())
	self.Weapon:SetNextSecondaryFire(CurTime() + self.Weapon:SequenceDuration())
	return true
end

function SWEP:Reload()
	self.Weapon:DefaultReload(self.ReloadAnim)
	self:SetZoom(false)
	self:SetSights(false)
end

function SWEP:OnRestore()
	self.NextSecondaryAttack = 0
	self:SetZoom(false)
	self:SetSights(false)
end

function SWEP:SetupDataTables()
	self:DTVar("Bool", 3, "sights")
end

function SWEP:Think()
	if self.Owner:KeyDown(IN_ATTACK2) and self.Owner:KeyPressed(IN_ATTACK2) then
		self:SetSights(true)
		self:SetZoom(true)
	elseif self.Owner:KeyReleased(IN_ATTACK2) then
		self:SetSights(false)
		self:SetZoom(false)
	end
	
	self:JumpCheck()
	self:GroundCheck()
	self:MoveCheck()
	self:StillCheck()
	
	self:SecondaryThink()
end

function SWEP:SecondaryThink()
end

local jumpcheck = true
local groundcheck = true
function SWEP:JumpCheck()
	if self.Owner:KeyDown(IN_JUMP) and not self.Owner:IsOnGround() and jumpcheck then
		self.Owner:ViewPunch(Angle(1, 0, 0))
		self:SetJumpTime(CurTime())
		self.ConeAffect = 2
		
		jumpcheck = false
		groundcheck = true
	end
end
function SWEP:GroundCheck()
	if self.Owner:IsOnGround() and groundcheck then
		self.Owner:ViewPunch(Angle(0.25, 0, 0))
		self.ConeAffect = 1
	
		jumpcheck = true
		groundcheck = false
	end
end

local movecheck = true
local stillcheck = true
function SWEP:MoveCheck()
	if self.Owner:IsOnGround() and (self.Owner:KeyDown(IN_FORWARD) or self.Owner:KeyDown(IN_MOVELEFT) or self.Owner:KeyDown(IN_MOVERIGHT) or self.Owner:KeyDown(IN_BACK)) then
		if movecheck then
			local angle = Angle(0, 0, 0)
			if self.Owner:KeyDown(IN_FORWARD) or self.Owner:KeyDown(IN_BACK) then
				angle.pitch = 0.25
			end
			if self.Owner:KeyDown(IN_MOVELEFT) then
				angle.roll = -0.75
			elseif self.Owner:KeyDown(IN_MOVERIGHT) then
				angle.roll = 0.75
			end
			self.Owner:ViewPunch(angle)
			self.ConeAffect = 1.45
			
			movecheck = false
			stillcheck = true
		end
		self:SetMoveTime(CurTime())
	end
end
function SWEP:StillCheck()
	if self.Owner:IsOnGround() and not (self.Owner:KeyDown(IN_FORWARD) or self.Owner:KeyDown(IN_MOVELEFT) or self.Owner:KeyDown(IN_MOVERIGHT) or self.Owner:KeyDown(IN_BACK)) and stillcheck then
		self.Owner:ViewPunch(Angle(0.5, 0, 0))
		self.ConeAffect = 1
	
		movecheck = true
		stillcheck = false
	end
end

local IRONSIGHT_TIME = 0.25
function SWEP:GetViewModelPosition(pos, ang)
	if !self.IronSightsPos then return pos, ang end

	local bIron = self:GetSights()
	
	if bIron != self.bLastIron then
		self.bLastIron = bIron
		self.fIronTime = CurTime()
	end
	
	local fIronTime = self.fIronTime or 0

	if !bIron && fIronTime < CurTime() - IRONSIGHT_TIME then 
		return pos, ang 
	end
	
	local Mul = 1.0
	
	if fIronTime > CurTime() - IRONSIGHT_TIME then
		Mul = math.EaseInOut(Lerp((CurTime() - fIronTime)/IRONSIGHT_TIME, 0, 1), 0.4, 0.4)
		
		if (!bIron) then Mul = 1 - Mul end
		
		self.SwayScale = Lerp(Mul, 1, 0.1)
		self.BobScale = Lerp(Mul, 1, 0.1)
	end

	local Offset = self.IronSightsPos
	
	if self.IronSightsAng then
		ang = ang * 1
		ang:RotateAroundAxis( ang:Right(), self.IronSightsAng.x * Mul )
		ang:RotateAroundAxis( ang:Up(), self.IronSightsAng.y * Mul )
		ang:RotateAroundAxis( ang:Forward(), self.IronSightsAng.z * Mul )
	end
	
	local Right 	= ang:Right()
	local Up 		= ang:Up()
	local Forward 	= ang:Forward()

	pos = pos + Offset.x * Right * Mul
	pos = pos + Offset.y * Forward * Mul
	pos = pos + Offset.z * Up * Mul

	return pos, ang
end
